#include "Tile.h"
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <sstream>
#include <SDL/SDL.h>
#include <SDL/SDL_image.h>
using namespace std;
//******************************	Public Functions	******************************

// Default constructor
Tile::Tile() {
	m_tileFlag = 0;
	Position temp(0,0);
	m_bgNum = temp;
	m_name = "Unknown";
}

// Class constructor, starts with flag and name
// Exits are added later 
Tile::Tile(int a_tileFlag, string a_name, Position a_bgNum)
	:m_tileFlag(a_tileFlag), m_name(a_name), m_bgNum(a_bgNum) {
	for(int i = 0; i < 4; i++){
		m_arrowList[i] = 0;
	}
}

// Class deconstructor
Tile::~Tile() {
}

// Set flag
void Tile::setFlag(int a_tileFlag) {
	m_tileFlag = a_tileFlag;
}

// Set name
void Tile::setName(string a_name) {
	m_name = a_name;
}

// Set both flag and name, for convenience
void Tile::setFlagAndName(int a_tileFlag, string a_tileName) {
	setFlag(a_tileFlag);
	setName(a_tileName);
}

// Rotate tile clockwise
void Tile::rotateCW(void) {
	bool temp[4];
	for(int i=0;i<4;++i) {
		temp[i] = m_arrowList[i];
	}

	for(int i=0; i<4; ++i) {
		if(i == 0) {
			m_arrowList[0] = temp[3];
		} else {
			m_arrowList[i] = temp[i-1];
		}
	}
}

// Rotate tile counter-clockwise
void Tile::rotateCCW(void) {
	bool temp[4];
	for(int i=0;i<4;++i) {
		temp[i] = m_arrowList[i];
	}

	for(int i=0; i<4; ++i) {
		if(i == 3) {
			m_arrowList[3] = temp[0];
		} else {
			m_arrowList[i] = temp[i+1];
		}
	}
}

// Get flag
int Tile::getFlag(void) {
	return m_tileFlag;
}

// Get name
string Tile::getName(void) {
	return m_name;
}

// http://stackoverflow.com/questions/127027/how-to-check-my-byte-flag
bool Tile::hasExit(arrowDirection type) {
	return m_arrowList[type];
}

void Tile::setExit(arrowDirection type) {
	m_arrowList[type] = true;
}
// http://www.vipan.com/htdocs/bitwisehelp.html
void Tile::removeExit(arrowDirection type) {
	m_arrowList[type] = false;
}

string Tile::toString(){
	string temp;
	temp += " Name: ";
	temp += m_name;
	temp += " Flag: ";

	temp += getIntToStr(m_tileFlag);



	temp += " ArrowList: ";
	temp += m_arrowList[0]?"1":"0";
	temp += m_arrowList[1]?"1":"0";
	temp += m_arrowList[2]?"1":"0";
	temp += m_arrowList[3]?"1":"0";
	return temp;
}


SDL_Surface* Tile::loadTileImage(string a_fileName)
{
	/*--- Temp storage for image that will be loaded ---*/
	SDL_Surface* loadedImage = NULL;
	/*--- The one that we will use ---*/
	SDL_Surface* optimizedImage = NULL;
	/*--- Load the image ---*/
	loadedImage = SDL_LoadBMP(a_fileName.c_str());
	optimizedImage = SDL_DisplayFormat(loadedImage);
	return optimizedImage;
}
/*--- a_x & a_y coordinates of the tile ---*/
SDL_Surface* Tile::drawBackground(SDL_Surface* a_dest, SDL_Surface* a_source) {
	SDL_Rect image;
	image.x = m_bgNum.getX();
	image.y = m_bgNum.getY();
	image.w = TILE_BG_WIDTH;
	image.h = TILE_BG_HEIGHT;

	SDL_Rect dest = {0,0,0,0};
	SDL_BlitSurface(a_source, &image, a_dest, &dest);

	return a_dest;
}

SDL_Surface* Tile::drawIcon(SDL_Surface* a_dest, SDL_Surface* a_source, Position a_idArray[]) {
	SDL_Rect image;
	image.x = a_idArray[m_tileFlag].getX();
	image.y = a_idArray[m_tileFlag].getY();
	image.w = TILE_ICON_WIDTH;
	image.h = TILE_ICON_HEIGHT;

	Quadrants quad;
	SDL_Rect dest = {quad.quads[4].getX(),quad.quads[4].getY(),0,0};
	SDL_BlitSurface(a_source, &image, a_dest, &dest);

	return a_dest;
}

SDL_Surface* Tile::drawExits(SDL_Surface* a_dest, SDL_Surface* a_source) {
	SDL_Rect image;
	Quadrants quad;
	int tW = TILE_ICON_WIDTH;
	int tH = TILE_ICON_HEIGHT;
	int row = TILE_ARROW_ROW_START;
	image.w = tW;
	image.h = tH;

	for(int i=0;i<4;++i) {
		if(m_arrowList[i]) {
			image.x = i*tW;
			image.y = row*tH;
			if(i == 0) {
				SDL_Rect dest = {quad.quads[1].getX(),quad.quads[1].getY(),0,0};
				SDL_BlitSurface(a_source, &image, a_dest, &dest);
			}
			if(i == 1) {
				SDL_Rect dest = {quad.quads[5].getX(),quad.quads[5].getY(),0,0};
				SDL_BlitSurface(a_source, &image, a_dest, &dest);
			}
			if(i == 2) {
				SDL_Rect dest = {quad.quads[7].getX(),quad.quads[7].getY(),0,0};
				SDL_BlitSurface(a_source, &image, a_dest, &dest);
			}
			if(i == 3) {
				SDL_Rect dest = {quad.quads[3].getX(),quad.quads[3].getY(),0,0};
				SDL_BlitSurface(a_source, &image, a_dest, &dest);
			}
		}
	}
	return a_dest;
}

SDL_Surface* Tile::getTileSurface(SDL_Surface * a_buffer, SDL_Surface * a_sourceBG, SDL_Surface * a_sourceTile, Position a_idArray[]) {	
	SDL_Surface * tempSurface = SDL_ConvertSurface(a_buffer, a_buffer->format, SDL_SWSURFACE);
	tempSurface = drawBackground(tempSurface, a_sourceBG);
	tempSurface = drawIcon(tempSurface, a_sourceTile, a_idArray);
	tempSurface = drawExits(tempSurface, a_sourceTile);

	return tempSurface;
}